//
//  YouinRTCManager.m
//  YouinRTC
//
//  Created by lprison on 2021/9/12.
//

//#define URL @"https://live.youinsh.com/saastest/" // 测试
////#define URL @"https://live.youinsh.com/livestream/" // 正式



//SDK url
#define SDKURL00 @"https://test-live.junfenghuang.com/livestream/"//测试
#define SDKURL01 @"https://live.youinsh.com/livestreamapi/"//生产


//LiveJsonURL
#define LiveJsonURL00 @"https://qncdn.junfenghuang.com/jfhlivetest/"//测试
#define LiveJsonURL01 @"https://qncdn.youinsh.cn/saas_pro/"//生产

//websocket
#define webSocketUrl00 @"wss://test-live.junfenghuang.com/jfh_socket/st/"//测试
#define webSocketUrl01 @"wss://websocket.youinsh.com/socket/"//生产


#import "YouinRTCManager.h"
#import "RTCWebSocketManager.h"
#import <MJExtension/MJExtension.h>
#import "RTCNetWorkingManager.h"


@interface YouinRTCManager ()<QNRTCEngineDelegate,RTCWebSocketManagerDelegate,LCIMClientDelegate>
@property(nonatomic,strong) LCIMConversationQuery *query;
@property(nonatomic,strong) NSString *userToken;
@property(nonatomic,strong) NSString *qiniuRoomToken;
@property(nonatomic,strong) NSString *socketURL;
@property(nonatomic,strong) RTCWebSocketManager *socketManager;
@property(nonatomic,strong) NSTimer *timer;
@property(nonatomic,strong) NSTimer *timer1;
@property(nonatomic,strong) NSTimer *timer2;
@property(nonatomic,strong) NSString *enterpriseId;
@property(nonatomic,strong) NSString *roomId;
@property (nonatomic,strong) RTCUserInfoModel *userInfoModel;
@property(nonatomic,strong) NSString *userId;
@property(nonatomic,strong) NSString *chatUserId;
@property(nonatomic,strong) NSString *chatRoomId;
@property(nonatomic,assign) int retryCount;
@property(nonatomic,assign) int deleteCount;
@property(nonatomic,strong)NSDictionary *userInfoDic;
@property(nonatomic,strong)MessagesModel *roomModel;
@property(nonatomic,strong) NSString *YNUserId;
//请求地址
@property (nonatomic,copy) NSString *requestUrl;
//LiveJsonURL
@property (nonatomic,copy) NSString *jsonURL;
//webSocketUrl
@property (nonatomic,copy) NSString *socketWebUrl;

//判断是否为讲师和course_details的teacher_id是否相同，否则无法开播
//@property(nonatomic,strong)NSString *user_id;
@end

@implementation YouinRTCManager
static YouinRTCManager *_interface = nil;
static dispatch_once_t onceToken;



+ (instancetype)shardManager {
    dispatch_once(&onceToken, ^{
        _interface = [[super allocWithZone:NULL] init];
    });
    return _interface;
}

//用alloc返回也是唯一实例
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    return [YouinRTCManager shardManager];
}

//对对象使用copy也是返回唯一实例
- (instancetype)copyWithZone:(NSZone *)zone {
    return [YouinRTCManager shardManager];
}

//对对象使用mutablecopy也是返回唯一实例
- (instancetype)mutableCopyWithZone:(NSZone *)zone {
    return [YouinRTCManager shardManager];
}

- (instancetype)init {
    self = [super init];
    if (self) {
        
        
        self.engine = [[QNRTCEngine alloc] init];
        self.engine.delegate = self;
        self.hostInfoModel = [RTCUserInfoModel new];
        self.userList = [NSMutableArray new];
        self.audioTrack = [[QNTrackInfo alloc] initWithSourceType:QNRTCSourceTypeAudio master:YES];
        
        self.cameraTrack = [[QNTrackInfo alloc] initWithSourceType:(QNRTCSourceTypeCamera)
                                                               tag:@"gaoqing"
                                                            master:YES
                                                        bitrateBps:2500*1000
                                                   videoEncodeSize:CGSizeMake(720, 1280)];
        
        
//        self.manager.cameraTrack = [[QNTrackInfo alloc] initWithSourceType:(QNRTCSourceTypeCamera)
//                                                                       tag:nil
//                                                                    master:YES
//                                                                bitrateBps:2500*1000
//                                                           videoEncodeSize:CGSizeMake(720, 1280)];
        
        [self.cameraTrack setMaintainResolutionEnabled:YES];
        self.engine.videoFrameRate = 24;
        self.engine.sessionPreset = AVCaptureSessionPreset1280x720;
        [self readNSUserDefaults];
        [self initializeChat];
        
    }
    return self;
}


-(void)initSocket{
    
    // 进入房间开始连接leancloud和websocket
    
    self.socketURL = [NSString stringWithFormat:@"%@%@/%@/undefined/",self.socketWebUrl,_roomId,self.userInfoModel.userId];
    
    self.socketManager = [RTCWebSocketManager new];
    self.socketManager.serverURL = self.socketURL;
    [self.socketManager initWebSocket];
    self.socketManager.delegate = self;
    
    
}


// 初始化leanCloud
- (void)initializeChat{
    
    
    
    [LCApplication setApplicationId:@"BL0eDKFkzB8qmoWMYFxdCWFf-gzGzoHsz"
                          clientKey:@"Y2zyu6d0rUsxWNSaQKJDqQTk"
                    serverURLString:@"https://leancloud.youinsh.com"];
    
    
    LCObject *testObject = [LCObject objectWithClassName:@"TestObject"];
    [testObject setObject:@"Hello world!" forKey:@"words"];
    [testObject save];
    
}
// 开始获取token
-(void)initialize:(void (^)(BOOL, NSError * _Nullable))callback{
    
    
    NSDictionary *dic = @{@"app_id":self.app_id,@"app_secret":self.app_secret};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:[self.requestUrl stringByAppendingString:@"v1/account/auth-token/"] params:dic header:nil success:^(id  _Nonnull content) {
        
        if([content[@"code"] intValue] == 200){
            self.userToken = content[@"result"][@"access_token"];
            if(callback){
                callback(YES,nil);
            }
        }else{
            if(callback){
                callback(NO,[[NSError alloc] initWithDomain:@"ERROR" code:0 userInfo:content]);
            }
            
        }
        
    } failure:^(NSError * _Nonnull error) {
        if(callback){
            callback(NO,error);
        }
    }];
    
//    [BaseRequest requestPost:[URL stringByAppendingString:@"v1/account/auth-token/"] paramars:dic paramarsSite:@"" header:nil sucessBlock:^(id content) {
//
//        if([content[@"code"] intValue] == 200){
//            self.userToken = content[@"result"][@"access_token"];
//            if(callback){
//                callback(YES,nil);
//            }
//        }else{
//            if(callback){
//                callback(NO,[[NSError alloc] initWithDomain:@"ERROR" code:0 userInfo:content]);
//            }
//
//        }
//    } failure:^(NSError *error) {
//        if(callback){
//            callback(NO,error);
//        }
//    }];
}

// 进房
-(void)joinRoom:(NSString *)roomID callback:(void (^)(BOOL, NSError * _Nullable))callback{
    self.roomId = roomID;
    [self getCourseinfo:self.roomId];
    [self getRoomStatus:self.roomId];
    _timer2  = [NSTimer scheduledTimerWithTimeInterval:10 repeats:YES block:^(NSTimer * _Nonnull timer) {
        [self getWatchNumber:self.roomId];
    }];
    [[NSRunLoop currentRunLoop] addTimer:_timer2 forMode:NSRunLoopCommonModes];
    
    NSString *token = self.phone_pass_login_token.length == 0 ? self.userInfoModel.token : self.phone_pass_login_token;
    
    NSString *url = [NSString stringWithFormat:@"%@v1/course/system/fetch_room_token/%@/",self.requestUrl,roomID];
    NSDictionary *dic = @{@"authorization":[NSString stringWithFormat:@"JWT %@",token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestGet:url paramars:nil header:dic success:^(id  _Nonnull content) {
        if(((NSNumber *)content[@"code"]).intValue == 200){
            self.qiniuRoomToken = content[@"result"][@"qiniu_room_token"];
            if(self.userInfoDic){
                [self.engine joinRoomWithToken:self.qiniuRoomToken userData:[self.userInfoDic mj_JSONString]];
            }else{
                [self.engine joinRoomWithToken:self.qiniuRoomToken userData:nil];
            }
            
            if(callback){
                callback(YES,nil);
            }
        }else{
            if(callback){
                callback(NO,[[NSError alloc] initWithDomain:@"error" code:-1 userInfo:content]);
            }
        }
    } failure:^(NSError * _Nonnull error) {
        if(callback){
            callback(NO,error);
        }
    }];
//    [BaseRequest requestGet:url paramars:nil paramarsSite:@"" header:dic sucessBlock:^(id content) {
//        if(((NSNumber *)content[@"code"]).intValue == 200){
//            self.qiniuRoomToken = content[@"result"][@"qiniu_room_token"];
//            if(self.userInfoDic){
//                [self.engine joinRoomWithToken:self.qiniuRoomToken userData:[self.userInfoDic mj_JSONString]];
//            }else{
//                [self.engine joinRoomWithToken:self.qiniuRoomToken userData:nil];
//            }
//
//            if(callback){
//                callback(YES,nil);
//            }
//        }else{
//            if(callback){
//                callback(NO,[[NSError alloc] initWithDomain:@"error" code:-1 userInfo:content]);
//            }
//        }
//
//
//
//    } failure:^(NSError *error) {
//        if(callback){
//            callback(NO,error);
//        }
//
//    }];
}

-(NSDictionary *)readNSUserDefaults

{
    NSUserDefaults *userDefaultes = [NSUserDefaults standardUserDefaults];

    //读取字典类型NSDictionary类型的数据
    
    NSDictionary *dic =  [userDefaultes dictionaryForKey:@"userToken"];
    self.phone_pass_login_token = dic[@"token"];
    return dic;
}

-(void)removeToken{
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults setObject:nil forKey:@"userToken"];

    [userDefaults synchronize];
}

-(void)saveNSUserDefaults:(NSDictionary *)dic

{
    self.phone_pass_login_token = dic[@"token"];
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

    [userDefaults setObject:dic forKey:@"userToken"];

    [userDefaults synchronize];
    
}

// 绑定用户
-(void)bindUser:(NSString *)userId name:(NSString *)name avatar:(NSString *)avatar callback:(nonnull void (^)(BOOL, NSError * _Nullable))callback{
    
    
    self.userInfoDic = @{@"third_user_id":userId,@"nickname":name,@"avatar":avatar};
    NSString *token = [NSString stringWithFormat:@"JWT %@",self.userToken];
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:[self.requestUrl stringByAppendingString:@"v1/user/sdk_register_user/"] params:self.userInfoDic header:@{@"authorization":token} success:^(id  _Nonnull content) {
        RTCUserInfoModel *model = [RTCUserInfoModel mj_objectWithKeyValues:content[@"result"]];
        model.userName = name;
        model.avatar = avatar;
        model.userId = userId;
        self.userInfoModel = model;
        [self getQiuNiuID:^(BOOL success, NSError * _Nullable error) {
            
        }];
        NSDictionary *clientID = @{@"userId":model.youin_user_id,@"userName":name};
        self.chatUserId = [clientID mj_JSONString];
        [self clientWithClientID:self.chatUserId callback:nil];
        if(callback){
            callback(YES,nil);
        }
    } failure:^(NSError * _Nonnull error) {
        if(callback){
            callback(NO,error);
        }
    }];
    
//    [BaseRequest requestPost:[URL stringByAppendingString:@"v1/user/sdk_register_user/"] paramars:self.userInfoDic paramarsSite:@"" header:@{@"authorization":token} sucessBlock:^(id content) {
//        userInfoModel *model = [userInfoModel mj_objectWithKeyValues:content[@"result"]];
//        model.userName = name;
//        model.avatar = avatar;
//        model.userId = userId;
//        self.userInfoModel = model;
//        [self getQiuNiuID:^(BOOL success, NSError * _Nullable error) {
//
//        }];
//        NSDictionary *clientID = @{@"userId":model.youin_user_id,@"userName":name};
//        self.chatUserId = [clientID mj_JSONString];
//        [self clientWithClientID:self.chatUserId callback:nil];
//        if(callback){
//            callback(YES,nil);
//        }
//    } failure:^(NSError *error) {
//        if(callback){
//            callback(NO,error);
//        }
//    }];
    
}
-(void)loginIn:(NSString *)name password:(NSString *)password callback:(void (^)(NSDictionary * _Nonnull, NSError * _Nullable))callback{
    NSDictionary *dic = @{@"username":name,@"password":password};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:[self.requestUrl stringByAppendingString:@"v1/user/system/login/"] params:dic header:nil success:^(id  _Nonnull content) {
        [self getQiuNiuID:^(BOOL success, NSError * _Nullable error) {
            if(callback){
                callback(content[@"result"],nil);
            }
        }];
    } failure:^(NSError * _Nonnull error) {
        if(callback){
            callback(nil,error);
        }
    }];
    
//    [BaseRequest requestPost:[URL stringByAppendingString:@"v1/user/system/login/"] paramars:dic paramarsSite:@"" header:nil sucessBlock:^(id content) {
//        [self getQiuNiuID:^(BOOL success, NSError * _Nullable error) {
//            if(callback){
//                callback(content[@"result"],nil);
//            }
//        }];
//
//    } failure:^(NSError *error) {
//        if(callback){
//            callback(nil,error);
//        }
//    }];
}

//初始化，获取token
- (void)init:(NSDictionary *)userDic success:(successBloc)success failure:(nullable void (^)(NSError * nullable))failure
{

    NSString *urlStr = @"";
    NSString *jsonStr = @"";
    NSString *webStr = @"";
    
    if ([userDic[@"isProduction"] intValue] == 0) {
        urlStr = SDKURL00;
        jsonStr = LiveJsonURL00;
        webStr = webSocketUrl00;
    }else
    {
        urlStr = SDKURL01;
        jsonStr = LiveJsonURL01;
        webStr = webSocketUrl01;
    }
    self.requestUrl = urlStr;
    self.jsonURL = jsonStr;
    self.socketWebUrl = webStr;
    
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestGet:[self.requestUrl stringByAppendingString:@"v1/user/thirdUserInfo/"] paramars:userDic header:nil success:^(id  _Nonnull content) {
        self.phone_pass_login_token = content[@"result"][@"token"];
        self.YNUserId = content[@"result"][@"user_id"];
                
        [self getQiuNiuID:^(BOOL success, NSError * _Nullable error) {
            
        }];
        NSDictionary *dict = @{@"code":content[@"code"],@"msg":content[@"msg"],@"token":self.phone_pass_login_token};
        success(dict);
    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}

-(void)getQiuNiuID:(void (^)(BOOL, NSError * _Nullable))callback {
    NSString *token = @"";
    if(self.phone_pass_login_token.length > 0){
        token = [NSString stringWithFormat:@"JWT %@",self.phone_pass_login_token];
    }else{
        token = [NSString stringWithFormat:@"JWT %@",self.userInfoModel.token];
    }
    
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestGet:[self.requestUrl stringByAppendingString:@"v1/user/system/userinfo/"] paramars:nil header:@{@"authorization":token} success:^(id  _Nonnull content) {
        
        if(self.phone_pass_login_token.length > 0){
            NSString *name = content[@"result"][@"nickname"];
            NSString *userId = content[@"result"][@"id"];
            NSString *avatar = content[@"result"][@"image"];
            NSDictionary *clientID = @{@"userId":userId,@"userName":name};
            self.chatUserId = [clientID mj_JSONString];
            self.userInfoModel = [RTCUserInfoModel new];
            self.userInfoModel.qiniu_user_id = content[@"result"][@"user_id"];
            self.userInfoModel.youin_user_id = userId;
            self.userInfoModel.userName = name;
            self.userInfoModel.avatar = avatar;
            self.userInfoModel.userId = userId;
            self.userInfoModel.user_type = [content[@"result"][@"user_type"] intValue];
            self.userInfoModel.token = self.phone_pass_login_token;
            self.userInfoDic = @{@"third_user_id":userId,@"nickname":name,@"avatar":avatar};
            [self clientWithClientID:self.chatUserId callback:nil];
        }else{
            self.userInfoModel.qiniu_user_id = content[@"result"][@"user_id"];
        }
        if(callback){
            callback(YES,nil);
        }
        
    } failure:^(NSError * _Nonnull error) {
        if(callback){
            callback(YES,error);
        }
    }];
    
    
//    [BaseRequest requestGet:[URL stringByAppendingString:@"v1/user/system/userinfo/"] paramars:nil paramarsSite:@"" header:@{@"authorization":token} sucessBlock:^(id content) {
//
//        if(self.phone_pass_login_token.length > 0){
//            NSString *name = content[@"result"][@"nickname"];
//            NSString *userId = content[@"result"][@"id"];
//            NSString *avatar = content[@"result"][@"image"];
//            NSDictionary *clientID = @{@"userId":userId,@"userName":name};
//            self.chatUserId = [clientID mj_JSONString];
//            self.userInfoModel = [userInfoModel new];
//            self.userInfoModel.qiniu_user_id = content[@"result"][@"user_id"];
//            self.userInfoModel.youin_user_id = userId;
//            self.userInfoModel.userName = name;
//            self.userInfoModel.avatar = avatar;
//            self.userInfoModel.userId = userId;
//            self.userInfoModel.user_type = [content[@"result"][@"user_type"] intValue];
//            self.userInfoModel.token = self.phone_pass_login_token;
//            self.userInfoDic = @{@"third_user_id":userId,@"nickname":name,@"avatar":avatar};
//            [self clientWithClientID:self.chatUserId callback:nil];
//        }else{
//            self.userInfoModel.qiniu_user_id = content[@"result"][@"user_id"];
//        }
//        if(callback){
//            callback(YES,nil);
//        }
//
//    } failure:^(NSError *error) {
//        if(callback){
//            callback(YES,error);
//        }
//    }];
}



// 获取直播间信息
-(void)getCourseinfo:(NSString *)liveid{
    int random = arc4random() % 10000;
    NSString *url = [NSString stringWithFormat:@"%@json/course_%@_info.json?%d",self.jsonURL,liveid,random];
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestGet:url paramars:nil header:nil success:^(id  _Nonnull content) {
        CoursesModel *model = [CoursesModel mj_objectWithKeyValues:content];
        self.enterpriseId = model.enterprise_id;
        [self getEnterPrise:model.enterprise_id];
        self.chatRoomId = model.chat_room_id;
        [self joinGroup:self.chatRoomId callback:^(BOOL success, NSError * _Nullable error) {
            if(success){
                if([self.chatDelegate respondsToSelector:@selector(courseInfo:error:)]){
                    [self.chatDelegate courseInfo:model error:nil];
                }
            }
            if(error){
            }
        }];
        [self initSocket];
        
       
    } failure:^(NSError * _Nonnull error) {
        {
            if([self.chatDelegate respondsToSelector:@selector(courseInfo:error:)]){
                [self.chatDelegate courseInfo:nil error:error];
            }
        }
    }];

}

// 获取企业信息
-(void)getEnterPrise:(NSString *)enterID{
    
    NSString *url = [NSString stringWithFormat:@"%@v1/enterprise/enterprise_info/",self.requestUrl];
    NSDictionary *dic = @{@"authorization":[NSString stringWithFormat:@"JWT %@",self.userInfoModel.token]};
    
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestGet:url paramars:nil header:dic success:^(id  _Nonnull content) {
        RTCEnterpriseModel *model = [RTCEnterpriseModel mj_objectWithKeyValues:content[@"result"]];
        if([self.chatDelegate respondsToSelector:@selector(enterpriseInfo:error:)]){
            [self.chatDelegate enterpriseInfo:model error:nil];
        }
    } failure:^(NSError * _Nonnull error) {
        if([self.chatDelegate respondsToSelector:@selector(enterpriseInfo:error:)]){
            [self.chatDelegate enterpriseInfo:nil error:error];
        }
    }];
    
//    [BaseRequest requestGet:url paramars:@"" paramarsSite:@"" header:dic  sucessBlock:^(id content) {
//        EnterpriseModel *model = [EnterpriseModel mj_objectWithKeyValues:content[@"result"]];
//        if([self.chatDelegate respondsToSelector:@selector(enterpriseInfo:error:)]){
//            [self.chatDelegate enterpriseInfo:model error:nil];
//        }
//    } failure:^(NSError *error) {
//        if([self.chatDelegate respondsToSelector:@selector(enterpriseInfo:error:)]){
//            [self.chatDelegate enterpriseInfo:nil error:error];
//        }
//    }];
}

// 获取直播间状态信息
-(void)getRoomStatus:(NSString *)liveID{
    NSString *url = [NSString stringWithFormat:@"%@v1/course/user_static/%@/",self.requestUrl,liveID];
    NSDictionary *dic = @{@"authorization":[NSString stringWithFormat:@"JWT %@",self.userInfoModel.token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:nil header:dic success:^(id  _Nonnull content) {
        StatusModel *model = [StatusModel mj_objectWithKeyValues:content[@"result"]];
        
        // 是否被禁言
        self.isUserForbidden = model.is_forbidden;
        if([self.chatDelegate respondsToSelector:@selector(isUserForbidden:)]){
            [self.chatDelegate isUserForbidden:model.is_forbidden];
        }
        
        if([self.chatDelegate respondsToSelector:@selector(statusInfo:error:)]){
            [self.chatDelegate statusInfo:model error:nil];
        }
    } failure:^(NSError * _Nonnull error) {
        if([self.chatDelegate respondsToSelector:@selector(statusInfo:error:)]){
            [self.chatDelegate statusInfo:nil error:error];
            
        }
    }];
}

// 获取观看信息
-(void)getWatchNumber:(NSString *)liveid{
    NSString *url = [NSString stringWithFormat:@"%@v1/course/statistics_data/%@/",self.requestUrl,liveid];
    NSDictionary *dic = @{@"authorization":[NSString stringWithFormat:@"JWT %@",self.userInfoModel.token]};
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestGet:url paramars:nil header:dic success:^(id  _Nonnull content) {
        StatusModel *model = [StatusModel mj_objectWithKeyValues:content[@"result"]];
        if([self.chatDelegate respondsToSelector:@selector(statusInfo:error:)]){
            [self.chatDelegate statusInfo:model error:nil];
        }
       
    } failure:^(NSError * _Nonnull error) {
        if([self.chatDelegate respondsToSelector:@selector(statusInfo:error:)]){
            [self.chatDelegate statusInfo:nil error:error];
        }
    }];
    
//    [BaseRequest requestGet:url paramars:nil paramarsSite:@""  header:dic sucessBlock:^(id content) {
//        StatusModel *model = [StatusModel mj_objectWithKeyValues:content[@"result"]];
//        if([self.chatDelegate respondsToSelector:@selector(statusInfo:error:)]){
//            [self.chatDelegate statusInfo:model error:nil];
//        }
//
//    } failure:^(NSError *error) {
//        if([self.chatDelegate respondsToSelector:@selector(statusInfo:error:)]){
//            [self.chatDelegate statusInfo:nil error:error];
//        }
//    }];
}

#pragma mark - 获取直播间列表
- (void)liveListCourse:(int)page success:(successBloc)success failure:(nullable void (^)(NSError * nullable))failure
{
    NSString *token = [NSString stringWithFormat:@"JWT %@",self.phone_pass_login_token];
    NSString *url = [NSString stringWithFormat:@"%@v1/course/system/list_course/app/?page=%d&status=0",self.requestUrl,page];
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestGet:url paramars:nil header:@{@"authorization":token} success:^(id  _Nonnull content) {
        LiveListModel *model = [LiveListModel mj_objectWithKeyValues:content];
        success(model);
    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}
#pragma mark - 创建直播间
- (void)getCreateCourse:(NSDictionary *)params successBlock:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    NSString *url = [NSString stringWithFormat:@"%@v1/course/system/create_course/",self.requestUrl];
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:params header:auth success:^(id  _Nonnull content) {
        
        NSDictionary *dicn = @{@"code":content[@"code"],@"msg":content[@"msg"]};
        successBlock(dicn);
        
    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}

#pragma mark - 更新直播间的封面
- (void)getUploadFile:(UIImage *)image successBlock:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    // 时间格式化
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    // 设置时间格式
    formatter.dateFormat = @"yyyyMMddHHmmss";
    // 文件名称
    NSString *fileName = [NSString stringWithFormat:@"%@.png", [formatter stringFromDate:[NSDate date]]];
    
    NSString *url = [NSString stringWithFormat:@"%@v1/course/aliyun/upload_file/",self.requestUrl];
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
    
    NSData *data=UIImageJPEGRepresentation(image, 0.5);
    if (data.length>1024*1024) {//1M以及以上
        data=UIImageJPEGRepresentation(image, 0.1);
    }else if (data.length>512*1024) {//0.5M-1M
        data=UIImageJPEGRepresentation(image, 0.3);
    }else if (data.length>200*1024) {//0.25M-0.5M
        data=UIImageJPEGRepresentation(image, 0.5);
    }
    
    NSDictionary *dicnt = @{@"file":@"binary",@"filename":fileName,@"type_name":@"image"};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestUpLoadFile:data withUrl:url params:dicnt header:auth progress:^(NSProgress * _Nonnull progress) {
        
    } success:^(id  _Nonnull content) {
        successBlock(content);
    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}

#pragma mark - 修改直播间信息
- (void)getModifyCourse:(NSDictionary *)params successBlock:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    NSString *url = [NSString stringWithFormat:@"%@v1/course/system/modify_course/%@/",self.requestUrl,params[@"liveId"]];
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:params header:auth success:^(id  _Nonnull content) {
        
        NSDictionary *dicn = @{@"code":content[@"code"],@"msg":content[@"msg"]};
        successBlock(dicn);
        
    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}
// 获取举手模式
-(void)getRoomHandsUp{
    
    NSString *token = [NSString stringWithFormat:@"JWT %@",self.userInfoModel.token];
    NSString *url = [NSString stringWithFormat:@"%@v1/course/join_room_type/?course_id=%@",self.requestUrl,self.roomId];
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestGet:url paramars:nil header:@{@"authorization":token} success:^(id  _Nonnull content) {
        if(((NSNumber*)content[@"result"][@"join_room_type"]).intValue == 1){
            self.isHandsUp = YES;
        }else{
            self.isHandsUp = NO;
        }
        if([self.delegate respondsToSelector:@selector(YouinRoomInfo:)]){
            [self.delegate YouinRoomInfo:[self getRoomInfo]];
        }
    } failure:^(NSError * _Nonnull error) {
        
    }];
    
//    [BaseRequest requestGet:url paramars:nil paramarsSite:@"" header:@{@"authorization":token} sucessBlock:^(id content) {
//        if(((NSNumber*)content[@"result"][@"join_room_type"]).intValue == 1){
//            self.isHandsUp = YES;
//        }else{
//            self.isHandsUp = NO;
//        }
//        if([self.delegate respondsToSelector:@selector(YouinRoomInfo:)]){
//            [self.delegate YouinRoomInfo:[self getRoomInfo]];
//        }
//
//    } failure:^(NSError *error) {
//
//    }];
}

-(void)beginLiveSuccess:(successBloc)success failure:(failure)failure{
    
    if (self.userInfoModel.user_type == 3||self.userInfoModel.user_type == 2||self.userInfoModel.user_type == 1) {
        NSString *token = [NSString stringWithFormat:@"JWT %@",self.phone_pass_login_token];
        NSString *url = [self.requestUrl stringByAppendingString:@"v1/course/weblive/notify/"];
        NSDictionary *dic = @{@"course_id":self.roomId,@"action":@"publish"};
        
        [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:dic header:@{@"authorization":token} success:^(id  _Nonnull content) {
            NSDictionary *dict = @{@"code":@200,@"msg":@"开播成功"};
            success(dict);
        } failure:^(NSError * _Nonnull error) {
            
        }];
        
//        [BaseRequest requestPost:url paramars:dic paramarsSite:@"" header:@{@"authorization":token} sucessBlock:^(id content) {
//            NSDictionary *dict = @{@"code":@200,@"msg":@"开播成功"};
//            success(dict);
//        } failure:^(NSError *error) {
//
//        }];
    }else{
        NSDictionary *dict = @{@"code":@403,@"msg":@"只有【管理员】，【子账号】，【讲师】，才可以开播"};
        failure(dict);
    }
    
}

- (void)stopLive:(BOOL)isEndLive suc:(void (^)(bool suc ))suc{

    NSString *token = [NSString stringWithFormat:@"JWT %@",self.phone_pass_login_token];
    if(isEndLive){
       
        NSString *url1 = [NSString stringWithFormat:@"%@v1/course/system/end_course/%@/",self.requestUrl,self.roomId];
        long currentTime =  [[NSDate date] timeIntervalSince1970]*1000;
        NSDictionary *messageDic = @{@"type":@"force_end",@"timeStamp":[NSNumber numberWithLong:currentTime],@"signaling_type":@"1479"};
        //
        NSString *message = [messageDic mj_JSONString];
        
        [self sendTextMessage:message callback:^(BOOL success, NSError * _Nullable error) {
            if(success){
                
                
                [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url1 params:nil header:@{@"authorization":token} success:^(id  _Nonnull content) {
                    
                    [self sendTextMessage:message callback:^(BOOL success, NSError * _Nullable error) {
                        if(suc){
                            suc(success);
                        }
                    }];
                } failure:^(NSError * _Nonnull error) {
//                    NSLog(@"panxin002");
                }];
        
            }else{
                [self sendTextMessage:message callback:^(BOOL success, NSError * _Nullable error) {
                    [self stopLive:true suc:^(bool suc) {
                        
                    }];
                }];
            }
            
        }];
    }else{
        
        NSString *url = [NSString stringWithFormat:@"%@v1/course/weblive/notify/",self.requestUrl];
        NSDictionary *dic = @{@"course_id":self.roomId,@"action":@"publish_done"};
        
        [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:dic header:@{@"authorization":token} success:^(id  _Nonnull content) {
            suc(content);
        } failure:^(NSError * _Nonnull error) {
//            failure(error);
        }];
        
    }
   
}


-(void)getHistoyNotice:(void (^)(NSArray<RTCLiveNoticeModel *> * _Nonnull))success failure:(void (^)(NSError * _Nonnull))failure{
    NSString *token = [NSString stringWithFormat:@"JWT %@",self.phone_pass_login_token];
    NSString *url = [NSString stringWithFormat:@"%@v1/course/notices/%@/",self.requestUrl,self.roomId];
    
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestGet:url paramars:nil header:@{@"authorization":token} success:^(id  _Nonnull content) {
        
        NSArray<RTCLiveNoticeModel *> *array = [RTCLiveNoticeModel mj_objectArrayWithKeyValuesArray:content[@"result"]];
        if(success){
            success(array);
        }
    } failure:^(NSError * _Nonnull error) {
        if(failure){
            failure(error);
        }
    }];
    
//    [BaseRequest requestGet:url paramars:nil paramarsSite:@"" header:@{@"authorization":token} sucessBlock:^(id content) {
//        NSArray<LiveNoticeModel *> *array = [LiveNoticeModel mj_objectArrayWithKeyValuesArray:content[@"result"]];
//        if(success){
//            success(array);
//        }
//    } failure:^(NSError *error) {
//        if(failure){
//            failure(error);
//        }
//    }];
}

-(void)sendNotice:(RTCLiveNoticeModel *)model success:(void (^)(bool))success failure:(void (^)(NSError * _Nonnull))failure{
    NSString *token = [NSString stringWithFormat:@"JWT %@",self.phone_pass_login_token];
    NSString *url = [NSString stringWithFormat:@"%@v1/course/notices/%@/",self.requestUrl,self.roomId];
    NSDictionary *dic = @{@"content":model.content,@"type":[NSNumber numberWithInt:model.type]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:dic header:@{@"authorization":token} success:^(id  _Nonnull content) {
        if([content[@"code"] intValue] == 200){
            if(success){
                success(true);
            }
        }else{
            if(failure){
                failure([NSError errorWithDomain:@"" code:0 userInfo:content]);
            }
        }
    } failure:^(NSError * _Nonnull error) {
        if(failure){
            failure(error);
        }
    }];
    
//    [BaseRequest requestPost:url paramars:dic paramarsSite:@"" header:@{@"authorization":token} sucessBlock:^(id content) {
//        if([content[@"code"] intValue] == 200){
//            if(success){
//                success(true);
//            }
//        }else{
//            if(failure){
//                failure([NSError errorWithDomain:@"" code:0 userInfo:content]);
//            }
//        }
//    } failure:^(NSError *error) {
//        if(failure){
//            failure(error);
//        }
//    }];
}

#pragma mark - 直播间商品列表
- (void)getProductWithLiveId:(NSString *)liveId successBloc:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    NSString *url = [NSString stringWithFormat:@"%@v1/course/system/my_product/%@/",self.requestUrl,liveId];
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:nil header:auth success:^(id  _Nonnull content) {
        NSArray<RTCGoodsListModel *> *model = [RTCGoodsListModel mj_objectArrayWithKeyValuesArray:content[@"result"]];
        successBlock(model);
    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}
#pragma mark - 企业下商品列表
- (void)getProductListLiveId:(NSString *)liveId withEnterpriseId:(NSString *)enterpriseId successBloc:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    NSString *url = [NSString stringWithFormat:@"%@v1/course/system/product_list/app/?enterprise_id=%@&course_id=%@",self.requestUrl,enterpriseId,liveId];
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestGet:url paramars:nil header:auth success:^(id  _Nonnull content) {
        EnterpriseProductModel *model = [EnterpriseProductModel mj_objectWithKeyValues:content];
        successBlock(model);
    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}
#pragma mark - 添加商品
- (void)getProductSet:(NSDictionary *)params withProducts:(NSMutableArray *)products successBloc:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    NSString *url = [NSString stringWithFormat:@"%@v1/course/system/product_set/%@/",self.requestUrl,params[@"course_id"]];
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};

    
    NSArray *dictArray = [RTCGoodsProductModel mj_keyValuesArrayWithObjectArray:products];
    NSMutableArray *arr = [NSMutableArray new];
    for (int i = 0; i < dictArray.count; i ++) {
        NSMutableDictionary *dict = dictArray[i];
        [dict setObject:@1 forKey:@"isShow"];
        [arr addObject:dict];
    }
    
    
//    GoodsProductModel *mdoel = products;
//    NSMutableDictionary *dict = mdoel.mj_keyValues;
//    [dict setObject:@1 forKey:@"isShow"];
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:params header:auth success:^(id  _Nonnull content) {

        if ([content[@"code"] intValue] == 200) {
            NSDictionary *dicnt = @{@"code":@200,@"msg":@"success"};
            successBlock(dicnt);
            
            NSDictionary *dic = @{@"type":@"product",@"status":@1,@"product":arr};
            NSString *message = [dic mj_JSONString];
            [self sendTextMessage:message callback:^(BOOL success, NSError * _Nullable error) {
//                NSLog(@"arr");
            }];
        }

    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}

#pragma mark - 上下架商品
- (void)getProductReset:(NSDictionary *)params successBloc:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    NSString *url = [NSString stringWithFormat:@"%@v1/course/system/product_set/%@/",self.requestUrl,params[@"course_id"]];
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:params header:auth success:^(id  _Nonnull content) {

        if ([content[@"code"] intValue] == 200) {
            
            NSDictionary *dic = @{@"type":@"product",@"status":@1,@"product":params,@"isShow":params[@"isShow"]};
            NSString *message = [dic mj_JSONString];
            [self sendTextMessage:message callback:^(BOOL success, NSError * _Nullable error) {
                NSLog(@"arr");
            }];
        }
        NSDictionary *dicnt = @{@"code":content[@"code"],@"msg":@"success"};
        successBlock(dicnt);

    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}


#pragma mark - 拖动商品
- (void)getMoveProductReset:(NSDictionary *)params successBloc:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    NSString *url = [NSString stringWithFormat:@"%@v1/course/system/product_set/%@/",self.requestUrl,params[@"course_id"]];
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:params header:auth success:^(id  _Nonnull content) {
        
        successBlock(content);
    
    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}

#pragma mark - 排序第二次调用
//- (void)updateSortRequest:(NSDictionary *)params successBloc:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
//{
//
//    NSDictionary *nextDict = @{@"id":params[@"ids"],@"sort_no":params[@"next"],@"product_id":params[@"nextId"],@"type":@"sort"};
//
//    NSString *url = [NSString stringWithFormat:@"%@v1/course/system/product_set/%@/",self.requestUrl,params[@"course_id"]];
//    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
//
//    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:nextDict header:auth success:^(id  _Nonnull content) {
//
//        successBlock(content);
//
//    } failure:^(NSError * _Nonnull error) {
//        failure(error);
//    }];
//}


#pragma mark - 置顶商品
- (void)getProductSetTop:(NSDictionary *)paramars successBloc:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    NSString *url = [NSString stringWithFormat:@"%@v1/course/system/product_settop/%@/",self.requestUrl,paramars[@"liveId"]];
    
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:paramars header:auth success:^(id  _Nonnull content) {
        
        if ([content[@"code"] intValue] == 200) {
            NSDictionary *dic = @{@"type":@"product",@"status":@1,@"product":@"product"};
            NSString *message = [dic mj_JSONString];
            [self sendTextMessage:message callback:^(BOOL success, NSError * _Nullable error) {
                
            }];
          
        }
        successBlock(content);
    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}

#pragma mark - 删除商品
- (void)getDelProductSet:(NSDictionary *)paramars successBloc:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    NSString *url = [NSString stringWithFormat:@"%@v1/course/system/del_product_set/%@/",self.requestUrl,paramars[@"id"]];
        
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:paramars header:auth success:^(id  _Nonnull content) {
        successBlock(content);
    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}

#pragma mark - 主播禁言所有人
- (void)forbiddenAll:(BOOL)isMute
{
    NSDictionary *dic = @{@"type":@"forbidden_all",@"status":[NSNumber numberWithBool:isMute]};
    NSString *message = [dic mj_JSONString];
    [self sendTextMessage:message callback:^(BOOL success, NSError * _Nullable error) {
        
    }];
}
#pragma mark - 黑名单列表
- (void)getListKickOut:(NSString *)params successBloc:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    NSString *url = [NSString stringWithFormat:@"%@v1/controller/system/list_kick_out/%@/",self.requestUrl,params];
        
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestGet:url paramars:nil header:auth success:^(id  _Nonnull content) {
                
        
        NSArray<RTCKickOutListModel *>*array = [RTCKickOutListModel mj_objectArrayWithKeyValuesArray:content[@"result"]];
        
        successBlock(array);
    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}
#pragma mark - 解开黑名单
- (void)getDelKickOut:(NSString *)params successBloc:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    NSString *url = [NSString stringWithFormat:@"%@v1/controller/system/del_kick_out/%@/",self.requestUrl,params];
        
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:nil header:auth success:^(id  _Nonnull content) {
        
        if ([content[@"code"] intValue] == 200) {
            NSDictionary *dic = @{@"status":@0,@"type":@"kick",@"userId":params};
            NSString *message = [dic mj_JSONString];
            [self sendTextMessage:message callback:^(BOOL success, NSError * _Nullable error) {

            }];
        }
        
        successBlock(content);
    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}

#pragma mark - 禁言列表
- (void)getListForbiddenWords:(NSString *)params successBloc:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    NSString *url = [NSString stringWithFormat:@"%@v1/controller/system/list_forbidden_words/%@/",self.requestUrl,params];
        
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestGet:url paramars:nil header:auth success:^(id  _Nonnull content) {
                
        NSArray<RTCKickOutListModel *>*array = [RTCKickOutListModel mj_objectArrayWithKeyValuesArray:content[@"result"]];
        
        successBlock(array);
    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}
#pragma mark - 解开禁言者
- (void)getDelForbiddenWords:(NSString *)params successBloc:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    NSString *url = [NSString stringWithFormat:@"%@v1/controller/system/del_forbidden_words/%@/",self.requestUrl,params];
        
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:nil header:auth success:^(id  _Nonnull content) {
        
        if ([content[@"code"] intValue] == 200) {
            
            //发LeanCloud消息
            NSDictionary *dic = @{@"type":@"forbidden",@"userId":params,@"status":@0};
            NSString *message = [dic mj_JSONString];
            [self sendTextMessage:message callback:^(BOOL success, NSError * _Nullable error) {
                
            }];
        }
        successBlock(content);
    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}

// 是否静音
-(void)getRoomIsMute{
    
    NSString *token = [NSString stringWithFormat:@"JWT %@",self.userInfoModel.token];
    NSString *url = [NSString stringWithFormat:@"%@v1/course/system/course_details/%@/",self.requestUrl,self.roomId];
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestGet:url paramars:nil header:@{@"authorization":token} success:^(id  _Nonnull content) {
        if(content[@"result"][@"isProhibit"]){
            self.isMuteAll = NO;
        }else{
            self.isMuteAll = YES;
        }

        if([self.delegate respondsToSelector:@selector(YouinRoomInfo:)]){
            [self.delegate YouinRoomInfo:[self getRoomInfo]];
        }
    } failure:^(NSError * _Nonnull error) {
        NSLog(@"getRoomIsMute");
    }];
    
//    [BaseRequest requestGet:url paramars:nil paramarsSite:@"" header:@{@"authorization":token} sucessBlock:^(id content) {
//        if(content[@"result"][@"isProhibit"]){
//            self.isMuteAll = NO;
//        }else{
//            self.isMuteAll = YES;
//        }
//
//        if([self.delegate respondsToSelector:@selector(YouinRoomInfo:)]){
//            [self.delegate YouinRoomInfo:[self getRoomInfo]];
//        }
//
//    } failure:^(NSError *error) {
//        NSLog(@"getRoomIsMute");
//    }];
}

// leanCloud登录
- (void)clientWithClientID:(NSString *)clientID callback:(void (^)(BOOL success, NSError * _Nullable error))callback{
    if([self.userId isEqualToString:clientID]){
        return;
    }
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
        NSError *error;
        self.client = [[LCIMClient alloc] initWithClientId:clientID error:&error];
        self.client.delegate = self;
        self.client.messageQueryCacheEnabled = false;
        self.query = [self.client conversationQuery];
        self.userId = clientID;
        if (error) {
            self.retryCount += 1;
            if(self.retryCount > 5){
                self.retryCount = 0;
                if(callback){
                    callback(false,error);
                }
                
            }else{
                // 重复登录
                [self clientWithClientID:clientID callback:nil];
            }
            
        } else {
            self.retryCount = 0;
            [self.client openWithCallback:^(BOOL succeeded, NSError * _Nullable error) {
                if(callback){
                    callback(succeeded,error);
                }
                
                
            }];
        }
    });
    
    
}

// 加入群聊
- (void)joinGroup:(NSString *)groupID callback:(nonnull void (^)(BOOL success, NSError *  _Nullable error))callback{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self.query getConversationById:groupID callback:^(LCIMConversation *conversation, NSError *error) {
            if(!error){
                self.retryCount = 0;
                self.conversation = conversation;
                [self.conversation addMembersWithClientIds:@[self.conversation.clientId] callback:^(BOOL succeeded, NSError *error) {
                    if (succeeded) {
                        [self YouinAction:YouinActionUserOnline];
                        [self YouinAction:YouinActionUserEnterRoom];
                        [self getRoomIsMute];
                        [self getRoomHandsUp];
//                        NSLog(@"加入群聊成功");
                        
//                        默认进来发的消息
                        NSDictionary *dict = @{@"type":@"IntoLiveRoom",@"userId":self.YNUserId,@"name":self.userInfoModel.userName};
                        
                        [self sendTextMessage:[dict mj_JSONString] callback:^(BOOL success, NSError * _Nullable error) {

                        }];
                        
                        if(callback){
                            callback(true,error);
                        }
                        
                    }
                }];
                
            }else{
                self.retryCount += 1;
                if(self.retryCount > 5){
                    self.retryCount = 0;
                    if(callback){
                        callback(false,error);
                    }
                    
                }else{
                    // 重复登录
                    [self joinGroup:groupID callback:^(BOOL success, NSError * _Nullable error) {
                        
                    }];
                }
            }
            
        }];
    });
    
    
}



#pragma mark QNRTC Chat Function

- (BOOL)isNum:(NSString *)checkedNumString {
    checkedNumString = [checkedNumString stringByTrimmingCharactersInSet:[NSCharacterSet decimalDigitCharacterSet]];
    if(checkedNumString.length > 0) {
        return NO;
    }
    return YES;
}

#pragma mark - 发送文字
-(void)sendTextMessage:(NSString *)text callback:(void (^)(BOOL success, NSError * _Nullable error))callback{
    NSString *textStr = @"";
    if([self isNum:text]){
        textStr = [text stringByAppendingString:@"<br>"];
    }else{
        textStr = text;
    }
    
    if(self.userInfoModel == nil){
        return;
    }
    
    LCIMTextMessage *message = [LCIMTextMessage messageWithText:textStr attributes:@{@"avatar":self.userInfoModel.avatar}];
    [self.conversation sendMessage:message callback:^(BOOL succeeded, NSError *error) {
        if(callback){
            callback(succeeded,error);
        }
        if(succeeded){
            // 发送成功
            BaseMsgModel *baseMessage = [BaseMsgModel new];
            baseMessage.sendTime =  [[NSDate date] timeIntervalSince1970];
            baseMessage.nickName = self.userInfoModel.userName;
            baseMessage.userId = self.userInfoModel.userId;
            baseMessage.avatar = self.userInfoModel.avatar;
            baseMessage.messageId = message.messageId;
            baseMessage.messageType = -1;
            baseMessage.text = text;
            baseMessage.conversationId = self.conversation.conversationId;
            
            if ([text containsString:@"referenceInfo"]) {//有引用消息
                NSDictionary *dicn = [self JSONObject:text];
                RTCTextModel *model = [RTCTextModel mj_objectWithKeyValues:dicn];
                
                baseMessage.msg = model.msg;
                baseMessage.referenceInfo = model.referenceInfo;
                baseMessage.type = @"referenceInfo";
            }
            
            //某某进来的消息
            if ([text containsString:@"IntoLiveRoom"]) {
                NSDictionary *dicn = [self JSONObject:text];
                baseMessage.type = @"IntoLiveRoom";
                baseMessage.userId = dicn[@"userId"];
                baseMessage.nickName = dicn[@"name"];
            }
            
            if([text mj_JSONObject][@"signaling_type"] > 0){
                __block NSTimer *time = [NSTimer timerWithTimeInterval:3 repeats:NO block:^(NSTimer * _Nonnull timer) {
                    [self deleteMessage:message];
                    [time invalidate];
                    time = nil;
                }];
                [[NSRunLoop currentRunLoop] addTimer:time forMode:NSRunLoopCommonModes];
                return;
            }
            // 文字图片信息回调
            if (![text containsString:@"product"]&&![text containsString:@"kick"]&&![text containsString:@"forbidden"]) {//上下架商品也会发消息，
                if([self.chatDelegate respondsToSelector:@selector(onNewMessageRecive:)]){
                    [self.chatDelegate onNewMessageRecive:baseMessage];
                }
            }
        }
    }];
}

#pragma mark - 发送图片
-(void)sendImageMessage:(UIImage *)image callback:(void (^)(BOOL, NSError * _Nullable))callback{
    NSString *filePath = [self saveImage:image ToDocmentWithFileName:@"image.png"];
    
    if([filePath isEqualToString:@""]){
        if(callback){
            callback(NO,[NSError errorWithDomain:@"save file error" code:nil userInfo:nil]);
        }
        return;
    }
    
    LCFile *file = [LCFile fileWithLocalPath:filePath error:nil];
    LCIMImageMessage *message = [LCIMImageMessage messageWithText:@"" file:file attributes:@{@"avatar":self.userInfoModel.avatar}];
    [self.conversation sendMessage:message callback:^(BOOL succeeded, NSError *error) {
        if(callback){
            callback(succeeded,error);
        }
        if(succeeded){
            // 发送成功
            BaseMsgModel *baseMessage = [BaseMsgModel new];
            baseMessage.sendTime =  [[NSDate date] timeIntervalSince1970];
            baseMessage.nickName = self.userInfoModel.userName;
            baseMessage.userId = self.userInfoModel.userId;
            baseMessage.avatar = self.userInfoModel.avatar;
            baseMessage.messageId = message.messageId;
            baseMessage.messageType = -2;
            baseMessage.image = image;
            baseMessage.conversationId = self.conversation.conversationId;
            // 文字图片信息回调
            if([self.chatDelegate respondsToSelector:@selector(onNewMessageRecive:)]){
                [self.chatDelegate onNewMessageRecive:baseMessage];
            }
            
        }
    }];
}

#pragma mark - 获取历史消息
-(void)getHistoryMessage:(int)count callback:(void (^)(NSArray<BaseMsgModel *> * _Nonnull, NSError * _Nullable error))callback{
    NSMutableArray *messageArray = [NSMutableArray new];
    
    __block NSTimer *time = [NSTimer timerWithTimeInterval:0.5 repeats:YES block:^(NSTimer * _Nonnull timer) {
        if(self.conversation){
            [time invalidate];
            time = nil;
            
            [self.conversation queryMessagesWithLimit:100 callback:^(NSArray *messages, NSError *error) {
                if(error){
                    if(callback){
                        callback(nil,error);
                    }
                    return;
                }
                NSLog(@"第一次查询成功！");
                // 以第一页的最早的消息作为开始，继续向前拉取消息
                // LCIMMessage *oldestMessage = [messages firstObject];
                for(LCIMTypedMessage *message in messages){
                    NSMutableDictionary *dic = [NSMutableDictionary new];
                    if(message.mediaType){
                        [dic setValue:[NSNumber numberWithInt:(int)message.mediaType] forKey:@"_lctype"];
                    }
                    if(message.text){
                        [dic setValue:message.text forKey:@"_lctext"];
                    }
                    if(message.attributes){
                        [dic setValue:message.attributes forKey:@"_lcattrs"];
                    }
                    if(message.file){
                        [dic setValue:message.file forKey:@"_lcfile"];
                    }
                    
                    
                    if([dic.allKeys containsObject:@"_lctext"]){
                        NSString *str = [dic[@"_lctext"] stringByReplacingOccurrencesOfString:@"\\" withString:@""];
                        str = [str stringByReplacingOccurrencesOfString:@"<br>" withString:@""];
                        NSDictionary *tempDic = [str mj_JSONObject];
                        if(tempDic == nil){
                            [dic setValue:@{@"text":str} forKey:@"_lctext"];
                        }else{
                            [dic setValue:tempDic forKey:@"_lctext"];
                        }
                    }
                    MessagesModel *model = [MessagesModel mj_objectWithKeyValues:dic];
                    
                    //上下架商品，发的消息，不用记录到列表中显示
                    if ([model._lctext.type isEqualToString:@"product"]) {
                        continue;
                    }
                    
                    if(model._lctext.signaling_type > 0 || (!model._lctext && !model._lcfile)){
                        continue;
                    }
                    
                    NSMutableDictionary *userDic = [NSMutableDictionary dictionaryWithDictionary:[message.clientId mj_JSONObject]];
                    RTCUserInfoModel *userModel = [RTCUserInfoModel mj_objectWithKeyValues:userDic];
                    
                    BaseMsgModel *baseMessage = [BaseMsgModel new];
                    baseMessage.sendTime = message.sendTimestamp;
                    baseMessage.nickName = userModel.userName;
                    baseMessage.userId = userModel.userId;
                    baseMessage.avatar = model._lcattrs.avatar;
                    baseMessage.messageId = message.messageId;
                    baseMessage.messageType = message.mediaType;
                    baseMessage.text = model._lctext.text;
                    baseMessage.imageUrl = model._lcfile.url;
                    baseMessage.conversationId = message.conversationId;
                    if([model._lctext.type isEqualToString:@"gift"]){
                        baseMessage.isGift = true;
                        baseMessage.giftName = model._lctext.giftName;
                        baseMessage.giftUrl = model._lctext.giftImg;
                        baseMessage.giftCount = model._lctext.giftCount;
                    }
                    //引用消息
                    baseMessage.msg = model._lctext.msg;
                    baseMessage.referenceInfo = model._lctext.referenceInfo;
                    baseMessage.type = model._lctext.type;

                    if (![baseMessage.type isEqualToString:@"referenceInfo"]) {//引用消息
                        if(baseMessage.nickName == nil || baseMessage.text == nil){
                            continue;
                        }
                    }
                    
                    [messageArray addObject:baseMessage];
                }
                if(callback){
                    callback(messageArray,error);
                }
            }];
        }
    }];
    
    [[NSRunLoop currentRunLoop] addTimer:time forMode:NSRunLoopCommonModes];
    
}
-(NSString *)saveImage:(UIImage*)image ToDocmentWithFileName:(NSString*)fileName{
    //2.保存到对应的沙盒目录中，具体代码如下：
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:fileName];   // 保存文件的名称
    BOOL result = [UIImagePNGRepresentation(image) writeToFile: filePath atomically:YES]; // 保存成功会返回YES
    if (result) {
        return filePath;
    }else{
        return @"";
    }
}

#pragma mark - 点赞
-(void)doLikeWithCount:(NSInteger)count Action:(successBloc)success failure:(void (^)(NSError * _Nonnull))failure{
    //只有在liveid有值的情况下调用
    if (![self strIsNULL:self.roomId]) {
        NSString *token = [NSString stringWithFormat:@"JWT %@",self.userInfoModel.token];
        NSString *url = [NSString stringWithFormat:@"%@v1/course/like/%@/",self.requestUrl,self.roomId];
        NSDictionary *dic = @{@"count":@(count),@"userId":self.YNUserId};
        NSDictionary *auth = @{@"Authorization":token};
        
        [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:dic header:auth success:^(id  _Nonnull content) {
            if(success){
                success(content[@"result"][@"like"]);
            }
        } failure:^(NSError * _Nonnull error) {
            
            failure(error);
        }];
    }
}

-(void)deleteMessage:(LCIMTextMessage*)message{
    
    self.deleteCount = 0;
    NSString *token = [NSString stringWithFormat:@"JWT %@",self.userInfoModel.token];
    NSString *url = [self.requestUrl stringByAppendingString:@"v1/controller/system/batch_del_message/"];
    NSString *userId = [NSString stringWithFormat:@"userId:%@",self.userInfoModel.youin_user_id];
    NSDictionary *dic = @{@"msg_list":@[@{@"from_client":userId,@"message_id":message.messageId,@"chatroom_id":self.chatRoomId,@"timestamp":[NSNumber numberWithLong:message.sendTimestamp]}]};
    
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:dic header:@{@"authorization":token} success:^(id  _Nonnull content) {
        
    } failure:^(NSError * _Nonnull error) {
        
    }];
    
//    [BaseRequest requestPost:url paramars:dic paramarsSite:@"" header:@{@"authorization":token} sucessBlock:^(id content) {
//
//
//    } failure:^(NSError *error) {
//
//    }];
}

#pragma mark QNRTC Function

-(void)leaveRoom{
    // 播放器销毁
    [self.engine leaveRoom];
    // 嘉宾下麦
    [self YouinAction:YouinActionUserLeave];
    // 定时器销毁
    [self.timer invalidate];
    self.timer = nil;
    [self.timer1 invalidate];
    self.timer1 = nil;
    [self.timer2 invalidate];
    self.timer2 = nil;
    // websocket断开
    [self.socketManager close];
    // 退出房间
    [self.conversation quitWithCallback:^(BOOL succeeded, NSError *error) {
        if (succeeded) {
            NSLog(@"退出成功！");
        }
    }];
    self.isInHome = NO;
    self.isPublish = NO;
    if([self.delegate respondsToSelector:@selector(YouinRoomInfo:)]){
        [self.delegate YouinRoomInfo:[self getRoomInfo]];
    }
}

-(NSArray<NSString *> *)getUserList{
    return  self.engine.userList;
}

- (void)startCapture{
    self.userInfoModel.is_camera_mute = NO;
    [self sendUserStatus];
    [self.engine startCapture];
}

-(void)stopCapture{
    self.userInfoModel.is_camera_mute = YES;
    [self sendUserStatus];
    [self.engine stopCapture];
}

-(void)publish{
    self.isPublish = YES;
    self.userInfoModel.interactive = YES;
    [self.engine publishTracks:@[self.audioTrack,self.cameraTrack]];
//    NSLog(@"==111==%@",self.audioTrack);
//    NSLog(@"==222==%@",self.cameraTrack);
    [self sendUserStatus];
    if([self.delegate respondsToSelector:@selector(YouinRoomInfo:)]){
        [self.delegate YouinRoomInfo:[self getRoomInfo]];
    }
}

-(void)unPublish{
    self.userInfoModel.interactive = NO;
    self.isPublish = NO;
    self.userInfoModel.hands_up_time = 0;
    self.userInfoModel.is_invited = false;
    [self.engine unpublishTracks:@[self.audioTrack,self.cameraTrack]];
    [self sendUserStatus];
    if([self.delegate respondsToSelector:@selector(YouinRoomInfo:)]){
        [self.delegate YouinRoomInfo:[self getRoomInfo]];
    }
}

- (void)changeCamera{
    [self.engine toggleCamera];
}

-(void)muteMicrophone:(BOOL)isMute{
    self.userInfoModel.is_mic_mute = isMute;
    [self.engine muteAudio:isMute];
    [self sendUserStatus];
}

- (void)muteSpeaker:(BOOL)isMute{
    self.engine.muteSpeaker = isMute;
    [self sendUserStatus];
}

#pragma mark - 禁言所有人
-(void)muteAllSpeaker:(BOOL)isMute{
    NSDictionary *dic = @{@"signaling_type":@21,@"closed_wheat":[NSNumber numberWithBool:isMute]};
    NSString *message = [dic mj_JSONString];
    [self sendTextMessage:message callback:^(BOOL success, NSError * _Nullable error) {
        
    }];
}


#pragma mark - 禁言某人
- (void)getAddForbidden:(NSDictionary *)params successBloc:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    NSString *url = [NSString stringWithFormat:@"%@v1/controller/system/add_forbidden_words/%@/",self.requestUrl,params[@"liveId"]];
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:params header:auth success:^(id  _Nonnull content) {
        if ([content[@"code"] intValue] == 200) {
            
            //发LeanCloud消息
            NSDictionary *dic = @{@"type":@"forbidden",@"userId":params[@"user_id"],@"status":@1};
            NSString *message = [dic mj_JSONString];
            [self sendTextMessage:message callback:^(BOOL success, NSError * _Nullable error) {
                
            }];
        }
        successBlock(content);

    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}

#pragma mark - 踢出直播间
- (void)getAddKickOut:(NSDictionary *)params successBloc:(successBloc)successBlock failure:(void (^)(NSError * _Nonnull error))failure
{
    NSString *url = [NSString stringWithFormat:@"%@v1/controller/system/add_kick_out/",self.requestUrl];
    NSDictionary *auth = @{@"authorization":[NSString stringWithFormat:@"jwt %@",self.phone_pass_login_token]};
    
    [[RTCNetWorkingManager sharedRTCNetWorkingManager] requestPost:url params:params header:auth success:^(id  _Nonnull content) {
        if ([content[@"code"] intValue] == 200) {
            //发LeanCloud消息
            NSDictionary *dic = @{@"status":@1,@"type":@"kick",@"userId":params[@"user_id"]};
            NSString *message = [dic mj_JSONString];
            [self sendTextMessage:message callback:^(BOOL success, NSError * _Nullable error) {

            }];
        }
        successBlock(content);

    } failure:^(NSError * _Nonnull error) {
        failure(error);
    }];
}



-(void)openSpeakerMike:(BOOL)isOpen userId:(NSString *)userId{
    NSDictionary *dic = @{@"signaling_type":@8,@"is_mic_mute":[NSNumber numberWithBool:isOpen],@"user_id":userId};
    NSString *message = [dic mj_JSONString];
    [self sendTextMessage:message callback:nil];
}

-(void)openSpeakerCamera:(BOOL)isOpen userId:(NSString *)userId{
    NSDictionary *dic = @{@"signaling_type":@10,@"is_camera_mute":[NSNumber numberWithBool:isOpen],@"user_id":userId};
    NSString *message = [dic mj_JSONString];
    [self sendTextMessage:message callback:nil];
}

-(void)inviteUserPublish:(NSString *)userId{
    NSDictionary *dic = @{@"signaling_type":@5,@"user_id":userId};
    NSString *message = [dic mj_JSONString];
    [self sendTextMessage:message callback:nil];
}

-(void)unPublishUser:(NSString *)userId{
    NSDictionary *dic = @{@"signaling_type":@11,@"user_id":userId};
    NSString *message = [dic mj_JSONString];
    [self sendTextMessage:message callback:nil];
}

-(void)agreeUserPublishApply:(BOOL)isAgree userId:(NSString *)userId{
    NSDictionary *dic = @{@"signaling_type":@4,@"user_id":userId,@"is_allow":[NSNumber numberWithBool:isAgree]};
    NSString *message = [dic mj_JSONString];
    [self sendTextMessage:message callback:nil];
}

-(void)setFillMode:(QNVideoFillModeType)fillMode{
    self.engine.fillMode = fillMode;
}

-(void)setCaptureDevicePosition:(AVCaptureDevicePosition)captureDevicePosition{
    self.engine.captureDevicePosition = captureDevicePosition;
}

- (void)setVideoOrientation:(AVCaptureVideoOrientation)videoOrientation{
    self.engine.videoOrientation = videoOrientation;
}

- (void)setSessionPreset:(NSString *)sessionPreset{
    self.engine.sessionPreset = sessionPreset;
}

- (void)setVideoFrameRate:(NSUInteger)videoFrameRate{
    self.engine.videoFrameRate = videoFrameRate;
}

- (void)setBeautifyModeOn:(BOOL)beautifyModeOn{
    [self.engine setBeautifyModeOn:beautifyModeOn];
}

- (void)setBeautify:(CGFloat)beautify{
    [self.engine setBeautify:beautify];
}

- (void)setWhiten:(CGFloat)whiten{
    [self.engine setWhiten:whiten];
}

- (void)setRedden:(CGFloat)redden{
    [self.engine setRedden:redden];
}



#pragma mark socket delegate
-(void)socketConnect{
    NSDictionary *dic = @{
        @"type":@"meeting",
        @"msg_type":@"end",
        @"msg":@{@"duration":@10, //10s发一次
                 @"enterprise_id":_enterpriseId} //企业id
    };
    NSString *str = [dic mj_JSONString];
    _timer  = [NSTimer scheduledTimerWithTimeInterval:10 repeats:YES block:^(NSTimer * _Nonnull timer) {
        [self.socketManager send:str];
    }];
    [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
}

#pragma mark - chat delegate 消息接收

- (void)conversation:(LCIMConversation *)conversation didReceiveTypedMessage:(LCIMTypedMessage *)message{
    
    NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:[message.content mj_JSONObject]];
    if([dic.allKeys containsObject:@"_lctext"]){
        NSString *str = [dic[@"_lctext"] stringByReplacingOccurrencesOfString:@"\\" withString:@""];
        str = [str stringByReplacingOccurrencesOfString:@"<br>" withString:@""];
        NSDictionary *tempDic = [str mj_JSONObject];
        if(tempDic == nil){
            [dic setValue:@{@"text":str} forKey:@"_lctext"];
        }else{
            [dic setValue:tempDic forKey:@"_lctext"];
        }
    }
    
    
    
    MessagesModel *model = [MessagesModel mj_objectWithKeyValues:dic];
    self.roomModel = model;
    if(model._lctext.signaling_type > 0){
        if([[NSString stringWithFormat:@"%@",model._lctext.user_id] isEqualToString:self.userInfoModel.youin_user_id] || [[NSString stringWithFormat:@"%@",model._lctext.user_id] isEqualToString:self.userInfoModel.qiniu_user_id]){
            
            if(model._lctext.signaling_type == 3){
                self.applyUserInfoModel = [RTCUserInfoModel new];
                self.applyUserInfoModel.userName = model._lctext.userName;
                self.applyUserInfoModel.userId = model._lctext.user_id;
                self.applyUserInfoModel.avatar = model._lcattrs.avatar;
                if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                    [self.delegate YouinSignalAction:YouinActionUserApplySpeak];
                }
            }
            
            if(model._lctext.signaling_type == 4){
                if(model._lctext.is_allow == 1){
                    if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                        [self.delegate YouinSignalAction:YouinActionHostAgreeUserSpeak];
                    }
                }else{
                    if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                        [self.delegate YouinSignalAction:YouinActionHostRefuseUserSpeak];
                    }
                }
                
            }
            if(model._lctext.signaling_type == 5){
                self.userInfoModel.is_invited = true;
                [self sendUserStatus];
                if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                    [self.delegate YouinSignalAction:YouinActionHostInviteUserSpeak];
                }
            }
            if(model._lctext.signaling_type == 6){
                if(model._lctext.is_allow == 0){
                    if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                        [self.delegate YouinSignalAction:YouinActionUserReplyRefuseSpeak];
                    }
                }
                if(model._lctext.is_allow == 1){
                    if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                        [self.delegate YouinSignalAction:YouinActionUserReplyAgreeSpeak];
                    }
                }
                if(model._lctext.is_allow == 0){
                    if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                        [self.delegate YouinSignalAction:YouinActionUserReplyOvertime];
                    }
                }
                
                
            }
            if(model._lctext.signaling_type == 8){
                if(model._lctext.is_mic_mute){
                    if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                        [self.delegate YouinSignalAction:YouinActionHostTurnOffMicrophone];
                    }
                }else{
                    if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                        [self.delegate YouinSignalAction:YouinActionHostTurnOnMicrophone];
                    }
                }
                
            }
            
            if(model._lctext.signaling_type == 10){
                if(model._lctext.is_camera_mute){
                    if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                        [self.delegate YouinSignalAction:YouinActionHostTurnOffCamera];
                    }
                }else{
                    if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                        [self.delegate YouinSignalAction:YouinActionHostTurnOnCamera];
                    }
                }
                
            }
            
            if(model._lctext.signaling_type == 11){
                if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                    [self.delegate YouinSignalAction:YouinActionHostUnpublishUser];
                }
            }
            
            if(model._lctext.signaling_type == 19){
                if(self.userInfoModel.role != 2){
                    self.userInfoModel.role = 2;
                    [self sendUserStatus];
                    if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                        [self.delegate YouinSignalAction:YouinActionHostSetMainSpeaker];
                    }
                }else{
                    self.userInfoModel.role = 0;
                    [self sendUserStatus];
                    if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                        [self.delegate YouinSignalAction:YouinActionHostCancelMainSpeaker];
                    }
                }
                
            }
            
            if(model._lctext.signaling_type == 28){
                if(self.userInfoModel.role != 4){
                    self.userInfoModel.role = 4;
                    [self sendUserStatus];
                    if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                        [self.delegate YouinSignalAction:YouinActionHostSetAssistantuser];
                    }
                }else{
                    self.userInfoModel.role = 0;
                    [self sendUserStatus];
                    if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                        [self.delegate YouinSignalAction:YouinActionHostCancelAssistantuser];
                    }
                }
                
            }
            
        }
        
        if(model._lctext.signaling_type == 1){
            [self handleUserList:model];
            if(model._lctext.role == 1){
                self.hostInfoModel.avatar = model._lcattrs.avatar;
                self.hostInfoModel.userName = model._lctext.userName;
                self.hostInfoModel.is_mic_mute = model._lctext.is_mic_mute;
                self.hostInfoModel.is_camera_mute = model._lctext.is_camera_mute;
                if([self.delegate respondsToSelector:@selector(YouinRoomInfo:)]){
                    [self.delegate YouinRoomInfo:[self getRoomInfo]];
                }
            }
            
        }
        if(model._lctext.signaling_type == 2){
            [self handleUserList:model];
            if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                [self.delegate YouinSignalAction:YouinActionUserEnterRoom];
            }
        }
        
        
        if(model._lctext.signaling_type == 12){
            if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                [self.delegate YouinSignalAction:YouinActionUserDidNotSpeak];
            }
        }
        if(model._lctext.signaling_type == 14){
            [self handleUserList:model];
            if([self.delegate respondsToSelector:@selector(YouinSignalAction:)]){
                [self.delegate YouinSignalAction:YouinActionUserLeave];
            }
        }
        
        
        
        if(model._lctext.signaling_type == 21){
            if(model._lctext.closed_wheat){
                self.isMuteAll = YES;
            }else{
                self.isMuteAll = NO;
            }
            if([self.delegate respondsToSelector:@selector(YouinRoomInfo:)]){
                [self.delegate YouinRoomInfo:[self getRoomInfo]];
            }
        }
        
        if(model._lctext.signaling_type == 24){
            if(model._lctext.wheat_mode == 1){
                self.isHandsUp = YES;
            }else{
                self.isHandsUp = NO;
            }
            if([self.delegate respondsToSelector:@selector(YouinRoomInfo:)]){
                [self.delegate YouinRoomInfo:[self getRoomInfo]];
            }
        }
        return;
    }
    
    //实时更新点赞
    if ([model._lcattrs.ws_type isEqualToString:@"update_like_count"]) {
        
        if([self.delegate respondsToSelector:@selector(youinManager:likeInfo:)]){
            [self.delegate youinManager:self likeInfo:model._lcattrs];
        }
    }
    
    //用户信息
    NSMutableDictionary *userDic = [NSMutableDictionary dictionaryWithDictionary:[message.clientId mj_JSONObject]];
    RTCUserInfoModel *userModel = [RTCUserInfoModel mj_objectWithKeyValues:userDic];
    
    BaseMsgModel *baseMessage = [BaseMsgModel new];
    baseMessage.sendTime = message.sendTimestamp;
    baseMessage.nickName = userModel.userName;
    baseMessage.userId = userModel.userId;
    baseMessage.avatar = model._lcattrs.avatar;
    baseMessage.messageId = message.messageId;
    baseMessage.messageType = message.mediaType;
    baseMessage.text = model._lctext.text;
    baseMessage.imageUrl = model._lcfile.url;
    baseMessage.conversationId = message.conversationId;
    
    baseMessage.msg = model._lctext.msg;
    baseMessage.referenceInfo = model._lctext.referenceInfo;
    baseMessage.type = model._lctext.type;
    
    if([model._lctext.type isEqualToString:@"gift"]){
        baseMessage.isGift = true;
        baseMessage.giftName = model._lctext.giftName;
        baseMessage.giftUrl = model._lctext.giftImg;
        baseMessage.giftCount = model._lctext.giftCount;
    }
    
    if (![baseMessage.type isEqualToString:@"IntoLiveRoom"]) {//这是用户进到直播间
//        if(baseMessage.text == nil && baseMessage.imageUrl == nil&&baseMessage.msg == nil){
//            return;
//        }
        if(baseMessage.nickName == nil){
            return;
        }
    }
    
    
    // 文字图片信息回调
    if(baseMessage.text || baseMessage.imageUrl || baseMessage.isGift || baseMessage.msg||[baseMessage.type isEqualToString:@"IntoLiveRoom"]){
        if([self.chatDelegate respondsToSelector:@selector(onNewMessageRecive:)]){
            [self.chatDelegate onNewMessageRecive:baseMessage];
        }
    }
}



-(void)sendUserStatus{
    if(self.modouleFunc == YouinModuleFuncLive){
        return;
    }
    NSDictionary *dic;
    @try {
        dic = @{@"signaling_type":@1,@"user_id":self.userInfoModel.qiniu_user_id,@"username":self.userInfoModel.userName,@"image":self.userInfoModel.avatar,@"is_mic_mute":[NSNumber numberWithBool:self.userInfoModel.is_mic_mute],@"is_camera_mute":[NSNumber numberWithBool:self.userInfoModel.is_camera_mute],@"is_invited":[NSNumber numberWithBool:self.userInfoModel.is_invited],@"hands_up_time":[NSNumber numberWithInt:self.userInfoModel.hands_up_time],@"interactive":[NSNumber numberWithInt:self.userInfoModel.interactive],@"role":[NSNumber numberWithInt:self.userInfoModel.role]};
    } @catch (NSException *exception) {
        
    } @finally {
        NSString *message = [dic mj_JSONString];
        [self sendTextMessage:message callback:nil];
    }
}

-(RTCRoomStatusModel*)getRoomInfo{
    RTCRoomStatusModel *model = [RTCRoomStatusModel new];
    model.hostUserInfo = self.hostInfoModel;
    model.isRoomHandsUp = self.isHandsUp;
    model.isUseInhome = self.isInHome;
    model.isUserPublish = self.isPublish;
    model.isRoomMuteAll = self.isMuteAll;
    return  model;
}

// 处理房间用户列表
// 1.十秒钟没有更新就删除用户
// 2.主动加入，数组没有就添加
// 3.主动离开，从数组中删除
-(void)handleUserList:(MessagesModel *)model{
    bool flag = false;
    int time = [self getTimestamp];
    int count = self.userList.count;
    NSMutableArray<RTCUserInfoModel*> *removeArray = [NSMutableArray new];
    RTCUserInfoModel *user = [RTCUserInfoModel new];
    user.userName = model._lctext.userName;
    user.youin_user_id = model._lctext.user_id;
    user.avatar = model._lcattrs.avatar;
    user.is_mic_mute = model._lctext.is_mic_mute;
    user.is_camera_mute = model._lctext.is_camera_mute;
    user.hands_up_time = model._lctext.hands_up_time;
    user.interactive = model._lctext.interactive;
    for(RTCUserInfoModel *i in self.userList){
        if([i.youin_user_id isEqualToString:model._lctext.user_id]){
            i.is_mic_mute = model._lctext.is_mic_mute;
            i.is_camera_mute = model._lctext.is_camera_mute;
            i.hands_up_time = model._lctext.hands_up_time;
            i.interactive = model._lctext.interactive;
            i.timestamp = time;
            
            
            flag = true;
        }
        if(time - i.timestamp > 15){
            [removeArray addObject:i];
        }
    }
    if(!flag){
        user.timestamp = time;
        [self.userList addObject:user];
    }
    
    for(RTCUserInfoModel *i in removeArray){
        [self.userList removeObject:i];
    }
    
    // 回调userList
    
    if([self.delegate respondsToSelector:@selector(userList:)]){
        [self.delegate userList:self.userList];
    }
    
    
}

-(int)getTimestamp{
    NSTimeInterval  time =  [[[NSDate alloc] init] timeIntervalSince1970];
    return (int)time;
}

#pragma mark 各种事件
-(void)YouinAction:(YouinAction)action{
    if(self.modouleFunc == YouinModuleFuncLive){
        return;
    }
    __block NSDictionary *dic;
    __block NSString *message;
    switch (action) {
        case YouinActionUserOnline:
        {
            dic = @{@"signaling_type":@1,@"user_id":self.userInfoModel.qiniu_user_id,@"username":self.userInfoModel.userName,@"image":self.userInfoModel.avatar,@"is_mic_mute":[NSNumber numberWithBool:self.userInfoModel.is_mic_mute],@"is_camera_mute":[NSNumber numberWithBool:self.userInfoModel.is_camera_mute],@"is_invited":[NSNumber numberWithBool:self.userInfoModel.is_invited],@"hands_up_time":[NSNumber numberWithInt:self.userInfoModel.hands_up_time],@"interactive":[NSNumber numberWithInt:self.userInfoModel.interactive],@"role":[NSNumber numberWithInt:self.userInfoModel.role]};
            message = [dic mj_JSONString];
            [self sendTextMessage:message callback:nil];
            _timer1  = [NSTimer scheduledTimerWithTimeInterval:10 repeats:YES block:^(NSTimer * _Nonnull timer) {
                dic = @{@"signaling_type":@1,@"user_id":self.userInfoModel.qiniu_user_id,@"username":self.userInfoModel.userName,@"image":self.userInfoModel.avatar,@"is_mic_mute":[NSNumber numberWithBool:self.userInfoModel.is_mic_mute],@"is_camera_mute":[NSNumber numberWithBool:self.userInfoModel.is_camera_mute],@"is_invited":[NSNumber numberWithBool:self.userInfoModel.is_invited],@"hands_up_time":[NSNumber numberWithInt:self.userInfoModel.hands_up_time],@"interactive":[NSNumber numberWithInt:self.userInfoModel.interactive],@"role":[NSNumber numberWithInt:self.userInfoModel.role]};
                message = [dic mj_JSONString];
                [self sendTextMessage:message callback:nil];
            }];
            [[NSRunLoop currentRunLoop] addTimer:_timer1 forMode:NSRunLoopCommonModes];
        }
            break;
        case YouinActionUserEnterRoom:
        {
            dic = @{@"signaling_type":@2,@"username":self.userInfoModel.userName};
            message = [dic mj_JSONString];
            [self sendTextMessage:message callback:nil];
        }
            break;
        case YouinActionUserApplySpeak:
        {
            dic = @{@"signaling_type":@3,@"username":self.userInfoModel.userName,@"user_id":self.userInfoModel.qiniu_user_id};
            self.userInfoModel.hands_up_time =  [[NSDate date] timeIntervalSince1970];
            message = [dic mj_JSONString];
            [self sendTextMessage:message callback:nil];
        }
            break;
        case YouinActionHostAgreeUserSpeak:
        {
            dic = @{@"signaling_type":@4,@"is_allow":@1,@"user_id":self.userInfoModel.qiniu_user_id};
            message = [dic mj_JSONString];
            [self sendTextMessage:message callback:nil];
        }
            break;
        case YouinActionHostRefuseUserSpeak:
        {
            dic = @{@"signaling_type":@4,@"is_allow":@0,@"user_id":self.userInfoModel.qiniu_user_id};
            message = [dic mj_JSONString];
            [self sendTextMessage:message callback:nil];
        }
            break;
        case YouinActionHostInviteUserSpeak:
        {
            dic = @{@"signaling_type":@5,@"user_id":self.userInfoModel.qiniu_user_id};
            message = [dic mj_JSONString];
            [self sendTextMessage:message callback:nil];
        }
            break;
        case YouinActionUserReplyRefuseSpeak:
        {
            dic = @{@"signaling_type":@6,@"user_id":self.userInfoModel.qiniu_user_id,@"username":self.userInfoModel.userName,@"is_allow":@0};
            message = [dic mj_JSONString];
            [self sendTextMessage:message callback:nil];
        }
            break;
        case YouinActionUserReplyAgreeSpeak:
        {
            dic = @{@"signaling_type":@6,@"user_id":self.userInfoModel.qiniu_user_id,@"username":self.userInfoModel.userName,@"is_allow":@1};
            message = [dic mj_JSONString];
            self.userInfoModel.is_invited = false;
            [self sendTextMessage:message callback:nil];
        }
            break;
        case YouinActionUserReplyOvertime:
        {
            dic = @{@"signaling_type":@6,@"user_id":self.userInfoModel.qiniu_user_id,@"username":self.userInfoModel.userName,@"is_allow":@2};
            message = [dic mj_JSONString];
            [self sendTextMessage:message callback:nil];
        }
            break;
        case YouinActionHostTurnOnMicrophone:
        {
            dic = @{@"signaling_type":@8,@"user_id":self.userInfoModel.qiniu_user_id,@"is_mic_mute":@1};
            message = [dic mj_JSONString];
            [self sendTextMessage:message callback:nil];
        }
            break;
        case YouinActionHostTurnOffMicrophone:
        {
            dic = @{@"signaling_type":@8,@"user_id":self.userInfoModel.qiniu_user_id,@"is_mic_mute":@0};
            message = [dic mj_JSONString];
            [self sendTextMessage:message callback:nil];
        }
            break;
        case YouinActionHostTurnOnCamera:
        {
            dic = @{@"signaling_type":@10,@"user_id":self.userInfoModel.youin_user_id,@"is_camera_mute":@1};
            message = [dic mj_JSONString];
            [self sendTextMessage:message callback:nil];
        }
            break;
        case YouinActionHostTurnOffCamera:
        {
            dic = @{@"signaling_type":@10,@"user_id":self.userInfoModel.youin_user_id,@"is_camera_mute":@0};
            message = [dic mj_JSONString];
            [self sendTextMessage:message callback:nil];
        }
            break;
        case YouinActionHostUnpublishUser:
        {
            dic = @{@"signaling_type":@11,@"user_id":self.userInfoModel.qiniu_user_id};
            message = [dic mj_JSONString];
            [self sendTextMessage:message callback:nil];
        }
            break;
        case YouinActionUserDidNotSpeak:
        {
            dic = @{@"signaling_type":@12,@"user_id":self.userInfoModel.qiniu_user_id,@"username":self.userInfoModel.userName};
            message = [dic mj_JSONString];
            [self sendTextMessage:message callback:nil];
        }
            break;
        case YouinActionUserLeave:
        {
            dic = @{@"signaling_type":@14,@"user_id":self.userInfoModel.qiniu_user_id,@"username":self.userInfoModel.userName};
            message = [dic mj_JSONString];
            [self sendTextMessage:message callback:nil];
        }
            break;
        default:
            break;
    }
}



-(void)conversation:(LCIMConversation *)conversation kickedByClientId:(NSString *)clientId{
    self.isUserKickOut = YES;
    if([self.chatDelegate respondsToSelector:@selector(isUserKickOut:)]){
        [self.chatDelegate isUserKickOut:YES];
    }
}



#pragma mark QNRTC delegate

- (void)RTCEngine:(QNRTCEngine *)engine didFailWithError:(NSError *)error{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didFailWithError:)]){
        [self.delegate YouinRTC:engine didFailWithError:error];
    }
}

-(void)RTCEngine:(QNRTCEngine *)engine roomStateDidChange:(QNRoomState)roomState{
    if (QNRoomStateConnected == roomState) {
        if([self.delegate respondsToSelector:@selector(YouinRoomInfo:)]){
            [self.delegate YouinRoomInfo:[self getRoomInfo]];
        }
        self.isInHome = YES;
    }
    if([self.delegate respondsToSelector:@selector(YouinRTC:roomStateDidChange:)]){
        [self.delegate YouinRTC:engine roomStateDidChange:roomState];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didPublishLocalTracks:(NSArray<QNTrackInfo *> *)tracks{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didPublishLocalTracks:)]){
        [self.delegate YouinRTC:engine didPublishLocalTracks:tracks];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didJoinOfRemoteUserId:(NSString *)userId userData:(NSString *)userData{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didJoinOfRemoteUserId:userData:)]){
        [self.delegate YouinRTC:engine didJoinOfRemoteUserId:userId userData:userData];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didLeaveOfRemoteUserId:(NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didLeaveOfRemoteUserId:)]){
        [self.delegate YouinRTC:engine didLeaveOfRemoteUserId:userId];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didSubscribeTracks:(NSArray<QNTrackInfo *> *)tracks ofRemoteUserId:(NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didSubscribeTracks:ofRemoteUserId:)]){
        [self.delegate YouinRTC:engine didSubscribeTracks:tracks ofRemoteUserId:userId];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didSubscribeProfileChanged:(nonnull NSArray<QNTrackInfo *> *)tracks ofRemoteUserId:(nonnull NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didSubscribeProfileChanged:ofRemoteUserId:)]){
        [self.delegate YouinRTC:engine didSubscribeProfileChanged:tracks ofRemoteUserId:userId];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didPublishTracks:(nonnull NSArray<QNTrackInfo *> *)tracks ofRemoteUserId:(nonnull NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didUnPublishTracks:ofRemoteUserId:)]){
        [self.delegate YouinRTC:engine didPublishTracks:tracks ofRemoteUserId:userId];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didUnPublishTracks:(nonnull NSArray<QNTrackInfo *> *)tracks ofRemoteUserId:(nonnull NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didUnPublishTracks:ofRemoteUserId:)]){
        [self.delegate YouinRTC:engine didUnPublishTracks:tracks ofRemoteUserId:userId];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didKickoutByUserId:(nonnull NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didKickoutByUserId:)]){
        [self.delegate YouinRTC:engine didKickoutByUserId:userId];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didAudioMuted:(BOOL)muted ofTrackId:(nonnull NSString *)trackId byRemoteUserId:(nonnull NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didAudioMuted:ofTrackId:byRemoteUserId:)]){
        [self.delegate YouinRTC:engine didAudioMuted:muted ofTrackId:trackId byRemoteUserId:userId];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didVideoMuted:(BOOL)muted ofTrackId:(nonnull NSString *)trackId byRemoteUserId:(nonnull NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didVideoMuted:ofTrackId:byRemoteUserId:)]){
        [self.delegate YouinRTC:engine didVideoMuted:muted ofTrackId:trackId byRemoteUserId:userId];
    }
}

- (QNVideoRender *)RTCEngine:(QNRTCEngine *)engine firstVideoDidDecodeOfTrackId:(NSString *)trackId remoteUserId:(NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:firstVideoDidDecodeOfTrackId:remoteUserId:)]){
        return [self.delegate YouinRTC:engine firstVideoDidDecodeOfTrackId:trackId remoteUserId:userId];
    }else{
        return  nil;
    }
    
}

- (void)RTCEngine:(QNRTCEngine *)engine didDetachRenderView:(nonnull UIView *)renderView ofTrackId:(nonnull NSString *)trackId remoteUserId:(nonnull NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didDetachRenderView:ofTrackId:remoteUserId:)]){
        [self.delegate YouinRTC:engine didDetachRenderView:renderView ofTrackId:trackId remoteUserId:userId];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didGetPixelBuffer:(nonnull CVPixelBufferRef)pixelBuffer ofTrackId:(nonnull NSString *)trackId remoteUserId:(nonnull NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didGetPixelBuffer:ofTrackId:remoteUserId:)]){
        [self.delegate YouinRTC:engine didGetPixelBuffer:pixelBuffer ofTrackId:trackId remoteUserId:userId];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didGetAudioBuffer:(nonnull AudioBuffer *)audioBuffer bitsPerSample:(NSUInteger)bitsPerSample sampleRate:(NSUInteger)sampleRate ofTrackId:(nonnull NSString *)trackId remoteUserId:(nonnull NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didGetAudioBuffer:bitsPerSample:sampleRate:ofTrackId:remoteUserId:)]){
        [self.delegate YouinRTC:engine didGetAudioBuffer:audioBuffer bitsPerSample:bitsPerSample sampleRate:sampleRate ofTrackId:trackId remoteUserId:userId];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine cameraSourceDidGetSampleBuffer:(nonnull CMSampleBufferRef)sampleBuffer{
    if([self.delegate respondsToSelector:@selector(YouinRTC:cameraSourceDidGetSampleBuffer:)]){
        [self.delegate YouinRTC:engine cameraSourceDidGetSampleBuffer:sampleBuffer];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine microphoneSourceDidGetAudioBuffer:(nonnull AudioBuffer *)audioBuffer{
    if([self.delegate respondsToSelector:@selector(YouinRTC:microphoneSourceDidGetAudioBuffer:)]){
        [self.delegate YouinRTC:engine microphoneSourceDidGetAudioBuffer:audioBuffer];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine microphoneSourceDidGetAudioBuffer:(nonnull AudioBuffer *)audioBuffer asbd:(nonnull const AudioStreamBasicDescription *)asbd{
    if([self.delegate respondsToSelector:@selector(YouinRTC:microphoneSourceDidGetAudioBuffer:asbd:)]){
        [self.delegate YouinRTC:engine microphoneSourceDidGetAudioBuffer:audioBuffer asbd:asbd];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didGetStatistic:(nonnull NSDictionary *)statistic ofTrackId:(nonnull NSString *)trackId userId:(nonnull NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didGetStatistic:ofTrackId:userId:)]){
        [self.delegate YouinRTC:engine didGetStatistic:statistic ofTrackId:trackId userId:userId];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine volume:(float)volume ofTrackId:(nonnull NSString *)trackId userId:(nonnull NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:volume:ofTrackId:userId:)]){
        [self.delegate YouinRTC:engine volume:volume ofTrackId:trackId userId:userId];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didCreateMergeStreamWithJobId:(nonnull NSString *)jobId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didCreateMergeStreamWithJobId:)]){
        [self.delegate YouinRTC:engine didCreateMergeStreamWithJobId:jobId];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didChangeAudioOutputToDevice:(QNAudioDeviceType)deviceType{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didChangeAudioOutputToDevice:)]){
        [self.delegate YouinRTC:engine didChangeAudioOutputToDevice:deviceType];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didReceiveMessage:(nonnull QNMessageInfo *)message{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didReceiveMessage:)]){
        [self.delegate YouinRTC:engine didReceiveMessage:message];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didLeaveOfLocalSuccess:(BOOL)success{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didLeaveOfLocalSuccess:)]){
        [self.delegate YouinRTC:engine didLeaveOfLocalSuccess:success];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didCreateForwardJobWithJobId:(nonnull NSString *)jobId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didCreateForwardJobWithJobId:)]){
        [self.delegate YouinRTC:engine didCreateForwardJobWithJobId:jobId];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didReconnectedRemoteUserId:(nonnull NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didReconnectedRemoteUserId:)]){
        [self.delegate YouinRTC:engine didReconnectedRemoteUserId:userId];
    }
}

- (void)RTCEngine:(QNRTCEngine *)engine didReconnectingRemoteUserId:(nonnull NSString *)userId{
    if([self.delegate respondsToSelector:@selector(YouinRTC:didReconnectingRemoteUserId:)]){
        [self.delegate YouinRTC:engine didReconnectingRemoteUserId:userId];
    }
}

/**
 *  判断字符串是否为空
 */
-(BOOL)strIsNULL:(NSString *)str
{
    if ([str isEqualToString:@""]||str.length==0||[[str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]length]==0||[str isEqualToString:@"0"]) {
        return YES;
    }else{
        return NO;
    }
}


//json格式字符串转字典：
-(NSDictionary *)JSONObject:(NSString *)data {
    if (data == nil) {
        return nil;
    }
    NSData *jsonData;
        if([data isKindOfClass:[NSData class]]){
            jsonData = (NSData *)data;
        }
        else if([data isKindOfClass:[NSString class]]){
            jsonData = [data dataUsingEncoding:NSUTF8StringEncoding];
        }
        else{
           return nil;
        }
        
        NSError *err;
        
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
                             
                                                            options:NSJSONReadingMutableContainers
                             
                                                              error:&err];
        
        if(err) {
//            NSLog(@"111  %@",[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]);
//            NSLog(@"json解析失败：%@",err);
            
            return nil;
            
        }
    return dic;
}

@end
